package net

import (
	"log"
	"sync"
	"time"

	"github.com/gorilla/websocket"
)

// 现在最主要应该实现的是通过这个session进行游戏逻辑的维护

type Session struct {
	UserID   string
	Conn     *websocket.Conn
	SendChan chan []byte
	RoomID   string
	mu       sync.Mutex
	isAlive  bool
}

func NewSession(userID string, conn *websocket.Conn) *Session {
	return &Session{
		UserID:   userID,
		Conn:     conn,
		SendChan: make(chan []byte, 256),
		isAlive:  true,
	}
}

// 异步对响应进行处理
func (s *Session) ReadPump() {
	defer s.Close()

	for {
		_, message, err := s.Conn.ReadMessage()
		if err != nil {
			if websocket.IsUnexpectedCloseError(err) {
				log.Printf("用户%s异常断开: %v", s.UserID, err)
			}
			break
		}
		handleMessage(s, message)
	}
}

func (s *Session) WritePump() {
	ticker := time.NewTicker(pingInterval)
	defer ticker.Stop()

	for {
		select {
		case message, ok := <-s.SendChan:
			if !ok {
				s.write(websocket.CloseMessage, []byte{})
				return
			}
			if err := s.write(websocket.BinaryMessage, message); err != nil {
				log.Println("写入失败:", err)
				return
			}
		case <-ticker.C:
			if err := s.write(websocket.PingMessage, nil); err != nil {
				return
			}
		}
	}
}

func (s *Session) write(mt int, payload []byte) error {
	s.mu.Lock()
	defer s.mu.Unlock()
	return s.Conn.WriteMessage(mt, payload)
}

func (s *Session) Close() {
	sessionManager.Unregister(s)
	close(s.SendChan)
	s.Conn.Close()
	s.isAlive = false
}
